import javax.swing.*;

/**
 * StoreLogic
 * This is the "Brain" of the program which keeps a 
 * list of customers on the floor of the store and
 * an array with the queues of the store.
 * The amount of queues can be changed by changing
 * the MAXSIZE variable to another number.
 * @author Martin
 *
 */
public class StoreLogic {
	//	Local variables	
	private DefaultListModel _notInLineList;
	private MyQueue[] _queue;
	private final int MAXSIZE = 5;
	private int _openLines;
	
	/**
	 * Constructor
	 */
	public StoreLogic()
	{
		_notInLineList = new DefaultListModel();
		_queue = new MyQueue[MAXSIZE];
		for (int i = 0; i < MAXSIZE; i++)
		{
			_queue[i] = new MyQueue();
		}
		_queue[0].set_isOpen(true);
		_queue[1].set_isOpen(true);
		_openLines = 2;
	}
	
	// Methods
	
	/**
	 * Adds a customer to the store.
	 * Pre: The user must have filled in the information in AddCustomerFrame 
	 * and pressed add.
	 * Post: creates a new customer not in any line.
	 */
	public void addCustomer(Person aPerson)
	{
		_notInLineList.addElement(aPerson);
	}
	
	/**
	 * Moves a customer from the floor to a line.
	 * Pre: A person must be selected and the line must not be closed.
	 * Post: Adds the person at customerindex in the queue with the lineindex
	 * Then removes him from the queue.
	 */
	public void moveCustToQueue(int customerIndex, int lineIndex)
	{	
		_queue[lineIndex].enqueue((Person)_notInLineList.get(customerIndex));
		removeCustomer(customerIndex);
	}
	
	/**
	 * Checks for the first open line and then the shortest line.
	 * Pre: a line must be open.
	 * Post: returns the index in _queue of the shortest open line.
	 */
	public int checkShortLine()
	{	
		int shortestLine = 0;
		for (int i = 0;i < MAXSIZE;i++)
		{
			if (_queue[i].get_isOpen())
			{
				shortestLine = i;
				break;
			}
		}

		for (int i = shortestLine;i < MAXSIZE;i++)
		{
			if ((_queue[shortestLine].getSize() > _queue[i].getSize()) && _queue[i].get_isOpen())
			{
				shortestLine = i;
			}
		}
		return shortestLine;
	}
	
	/**
	 * Method for spreadin out customers from a closed to open ones
	 * Pre: the old line must not have been closed.
	 * Post: The Customers from the old line has been moved to other Lines.
	 */
	public void spreadOut(int aLineIndex)
	{
		while (_queue[aLineIndex].getSize() != 0)
		{
			_queue[checkShortLine()].enqueue((Person)_queue[aLineIndex].getCustomerInLineList().getElementAt(0));
			_queue[aLineIndex].dequeue();
		}
	}
	
	/**
	 * Removes a customer from a line
	 * Pre: an open line with customers in it must be selected.
	 * Post: Removes the first customer from selected line.
	 */
	public void serveCustomer(int lineIndex)
	{
		_queue[lineIndex].dequeue();
	}
	
	/**
	 * Removes a customer that is not in a line.
	 * Pre: a customer must be selected.
	 * Post: Removes a customer from the floor.
	 */
	public void removeCustomer(int aIndex)
	{
		_notInLineList.remove(aIndex);
	}
	
	// Getters & Setters
	
	/**
	 * Gets the amount of open lines.
	 * Pre: true
	 * Post: returns the number of open lines
	 */
	public int getOpenLines()
	{
		return _openLines;
	}

	/**
	 * Gets the maximum number of lines.
	 * Pre: true
	 * Post: returns the maximum open lines.
	 */
	public int getMaxSize()
	{
		return MAXSIZE;
	}

	/**
	 * Gets the list with people who are not in line.
	 * Pre: true
	 * Post: returns the list with people who are not in line.
	 */
	public DefaultListModel getNotInLine()
	{
		return _notInLineList;
	}

	/**
	 * Gets the list with people who are in a line.
	 * Pre: a open line must be selected.
	 * Post: returns the list with people who are in this line.
	 */
	public DefaultListModel getInLine(int aIndex)
	{
		return _queue[aIndex].getCustomerInLineList();
	}
	
	/**
	 * Gets the first person in the selected line.
	 * Pre: there must be a person in the selected line.
	 * Post: returns the selected person out on the floor.
	 */
	public Person getFirstPersonInLine(int aIndex)
	{
		return _queue[aIndex].getPerson(0);
	}
	
	/**
	 * Gets a person that is not in a line yet.
	 * Pre: a person on the floor must be selected.
	 * Post: returns the selected person out on the floor.
	 */
	public Person getPersonNotLine(int aIndex)
	{
		return (Person) _notInLineList.getElementAt(aIndex);
	}

	/**
	 * Gets if a line is open or not.
	 * Pre: true
	 * Post: returns true or false depending if the line is open or not
	 */
	public boolean getLineStatus(int aLine)
	{
		return _queue[aLine].get_isOpen();
	}

	/**
	 * Sets if a line is open or closed.
	 * Pre: the selected line must not be the last open one.
	 * Post: returns opens/closes the selected line and changes the number of _openLines
	 */
	public void setLineStatus(int aLine, boolean aStatus)
	{
		_queue[aLine].set_isOpen(aStatus);
		if (aStatus)
			_openLines = _openLines + 1;
		else
			_openLines = _openLines - 1;
	}
}
